<template>
<div>
    <!-- 搜索组件一级路由   $router.back()返回上一个页面-->
    <van-nav-bar left-arrow title="搜索中心" @click-left="$router.back()"></van-nav-bar>
    <!-- van-search提供的input值改变事件 -->
    <van-search
      show-action
      placeholder="请输入搜索关键词"
      shape="round"
      v-model.trim="keyword"
      @input="hGetSuggestionWithThrottle"
      >
      <div slot="action" @click="hSearch">搜索</div>
    </van-search>

    <!-- 联想建议 :title="item"用来显示内容,高亮的话不要title，用<div v-html="item"></div>展示
    高亮显示搜索关键字：
    需要对数据项进行再加工，以得到高亮效果的字符串,用计算属性
    v-if="keyword"当搜索时历史记录隐藏，显示搜索建议；当不搜索时相反
    -->
    <van-cell-group v-if="keyword">
      <van-cell
      v-for="(item,idx) in cSuggestion"
      :key="idx"
      @click="hSearchSuggestion(idx)"
      icon="search">
        <div v-html="item"></div>
      </van-cell>
    </van-cell-group>
    <!-- /联想建议 -->

    <!-- 搜索历史记录
    对于关闭按钮不希望冒泡到外层click，可以加修饰符stop
    -->
    <van-cell-group v-else>
      <van-cell title="历史记录">
      </van-cell>
      <van-cell
      v-for="(item, idx) in history"
      :key="idx"
      :title="item"
      @click="$router.push('/search/result?keyword=' + item)">
        <!-- 删除搜索记录 -->
        <van-icon name="close" @click.stop="hDelHistory(idx)"/>
      </van-cell>
    </van-cell-group>
    <!-- /搜索历史记录 -->
  </div>
</template>

<script>
import { getItem, setItem } from '@/utils/storage.js';
import { getSuggestion } from '@/api/search.js';
// 代码简洁之道： 消除魔术数
// 以常量的格式定义一个名字，用来保存localstorage信息
const LOCALSTORAGE_SEARCH_NAME = 'searchHistory';
export default {
  name: 'Search',
  props: { },
  data () {
    return {
      timer: null, // 定时器防抖和节流
      keyword: '', // 搜索关键字
      suggestion: [], // 当前搜索建议
      history: getItem(LOCALSTORAGE_SEARCH_NAME) || [] // 搜索历史记录，初始从本地取数据
    };
  },
  computed: {
    // 高亮显示搜索关键字：
    // str.replace(regexp|substr,newsubstr|function);
    // 简单的replace不能解决两个问题：替换多个和不区分大小写
    // 所以需要replace和正则搭配使用实现联想建议的高亮
    // 需要对数据项进行再加工，以得到高亮效果的字符串,用计算属性
    cSuggestion () {
      // 根据keyword 对 suggestion的每一项进行处理，实现搜索建议中高亮显示搜索关键字
      // g 全局匹配；i 不区分大小写
      const res = new RegExp(this.keyword, 'gi');
      // 计算属性：得到一个高亮新数组
      // 计算属性/map/replace都需要返回值return
      // return this.suggestion.map(str => {
      //   const newStr = str.replace(res, function (str) {
      //     return `<span style="color:red">${str}</span>`;
      //   });
      //   return newStr;
      // });
      // return一句话的话简化一下，省略return
      return this.suggestion.map(str => str.replace(res, str => `<span style="color:red">${str}</span>`));
    }
  },
  created () { },
  mounted () {
  },
  methods: {
    // 用户点击搜索按钮
    hSearch () {
      if (this.keyword === '') return;
      // 1.当前搜索关键字添加到搜索历史中
      this.addHistory(this.keyword);
      // 2.跳转到搜索结果页
      // 方法一：直接拼接
      // this.$router.push('/search/result?keyword=' + this.keyword);
      // 方法二：对象格式
      this.$router.push({
        path: '/search/result',
        query: {
          keyword: this.keyword
        }
      });
    },
    // 用户点击某个搜索建议
    hSearchSuggestion (idx) {
      // 1.当前搜索关键字添加到搜索历史中
      this.addHistory(this.suggestion[idx]);
      // 2.路由跳转，传递参数
      this.$router.push('/search/result?keyword=' + this.suggestion[idx]);
    },
    addHistory (str) {
      // 添加数据到搜索历史中
      // 搜索历史是一个数组，其中的元素不能重复
      // 最近搜索的记录应该在最前面
      // 要求：1. 加在数组最前面 。 2 后面还不能有重复项。
      // 解决：先查找，有相同的删除；然后添加
      const idx = this.history.findIndex(item => item === str);
      if (idx !== -1) {
        // 找到了
        this.history.splice(idx, 1);
      }
      this.history.unshift(str);

      // 存储到本地
      setItem(LOCALSTORAGE_SEARCH_NAME, this.history);
    },
    hDelHistory (idx) {
      this.history.splice(idx, 1);
      // 存储到本地
      setItem(LOCALSTORAGE_SEARCH_NAME, this.history);
    },

    // 搜索输入框值改变事件
    // input输入是高频操作，需要做降频处理，防抖和节流
    // 防抖0.5s，0.5s内不论请求多少次都被打断，重新请求，只执行第一次和最后一次
    // 节流0.3s，两次请求至少间隔0.3s，会执行多次
    // 这里推荐使用节流，用户体验比较好
    hGetSuggestionWithDebounce () {
      // 定时器实现防抖
      if (this.timer) {
        clearTimeout(this.timer);
      }
      this.timer = setTimeout(async () => {
        if (this.keyword === '') {
          this.suggestion = [];
          return;
        }
        // 只要搜索输入框内容发生变化，就要获取联想建议（自动补全）
        const result = await getSuggestion(this.keyword);
        console.log('搜索建议', result);
        this.suggestion = result.data.data.options;
      }, 0.5 * 1000);
    },
    hGetSuggestionWithThrottle () {
      // 定时器实现节流
      if (!this.timer) {
        // 只有this.timer是null才会去开启下一个定时器
        this.timer = setTimeout(async () => {
          this.timer = null;
          if (this.keyword === '') {
            this.suggestion = [];
            return;
          }
          // 只要搜索输入框内容发生变化，就要获取联想建议（自动补全）
          const result = await getSuggestion(this.keyword);
          console.log('搜索建议', result);
          this.suggestion = result.data.data.options;
        }, 0.3 * 1000);
      }
    }
  }
};
</script>

<style scoped lang='less'></style>
